package controllers.item;

import java.util.Random;

import org.junit.Test;

import util.math.GetKaiFangNumber;

import core.encryptionDecrypt.EncryptionDecrypt;

/**
 * 加密id 显示实体的基类
 * 
 * 
 */
public class SuperDisplay implements EncryptionDecrypt {
	private int a;
	private int b;
	private Long cha;
	/**
	 *  需要加密的属性sqlId
	 */
	private Long id;
	/**
	 *  加密后的id值;
	 */
	private Long encryptionId;
	protected SuperDisplay() {};
	public SuperDisplay(long id) throws Exception {
		int ab[] = this.randomAB();
		a = ab[0];
		b = ab[1];
		this.encryption(a, b, id);
	}

	// 数据库的ID均为正整数就不用考虑小数点问题了
	// 简单加密 解密 随机数random为一元一次函数系数 开根号 一元一次函数
	// 开根号 根据a奇偶确定开根后正负

	public Long encryption(int a, int b, Long id) throws Exception {
		if (a == 0)
			throw new Exception("a error ,a="+a);
		if (id == null)
			throw new Exception("id error,id=" + id);
		if (id.toString().contains("."))
			throw new Exception("id error,id=" + id);
		if (id < 0)
			throw new Exception(" id error,id=" + id);
		// 拿到能开方为整数的数
		long needEncryptionNumber = GetKaiFangNumber.getKaiFangNumber().get(id);
		// 被开方数与id间的差值
		this.cha = needEncryptionNumber - id;
		// 去小数点转为long 获得正开方数
		Long sqrt = new Long(String.valueOf(Math.sqrt(needEncryptionNumber))
				.split("\\.")[0]);
		// 线性方程系数a为负数则取负开方数
		if (a % 2 != 0)
			sqrt = sqrt - 2 * sqrt;
		this.encryptionId = linearEquationOneUnknown(a, b, sqrt);
		this.id=id;
		return encryptionId;
	}

	// 解密
//	public Long Decrypt(Long needDecryptNumber, Long cha) {
//		Long _sqrt = linearEquationOneUnknownDecrypt(this.a, this.b,
//				needDecryptNumber);
//		return _sqrt * _sqrt - cha;
//	}
/**
 * 获取sqlId
 * @return
 */
	public Long DecryptByDisplay() {
		Long _sqrt = linearEquationOneUnknownDecrypt(this.a, this.b,
				this.encryptionId);
		return _sqrt * _sqrt - this.cha;
	}

	// 随机生成参数a,b
	public int[] randomAB() {
		int[] res = new int[2];
		Random r = new Random();
		while (true) {
			res[0] = r.nextInt(18000) - 9000;
			if (res[0] != 0)
				break;
		}
		res[1] = r.nextInt(2000) - 1000;
		return res;
	}

	// 加密 綫性方程 ax+b
	public Long linearEquationOneUnknown(int a, int b, Long sqrt) {
		return a * sqrt + b;

	}

	// 解密 綫性方程
	public Long linearEquationOneUnknownDecrypt(int a, int b,
			Long needDecryptNumber) {
		return (needDecryptNumber - b) / a;
	}

	public static void main(String[] args) throws Exception {

		SuperDisplay sd = new SuperDisplay(6200l);

		System.out.println("res:" + sd.setABAndGetId());
		System.out.println("jiemi:" + sd.DecryptByDisplay());
	}
/**
 * 随机生成a，b生成新的加密id
 * @return
 * @throws Exception
 */
	public Long setABAndGetId() throws Exception {
		int[] ab = this.randomAB();
		this.a = ab[0];
		this.b = ab[1];
		return encryption(a, b, this.id);
	}

	// public Long getId() {
	// return id;
	// }



	public Long getEncryptionId() {
		return encryptionId;
	}

	public void setEncryptionId(Long encryptionId) {
		this.encryptionId = encryptionId;
	}
}
